package com.example.homework

import android.content.Context
import android.graphics.*
import android.media.MediaPlayer
import android.util.AttributeSet
import android.view.View
import android.view.ViewTreeObserver
import kotlin.math.cos
import kotlin.math.sin
import kotlin.random.Random

class GameView @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0
) : View(context, attrs, defStyleAttr) {

    // 游戏常量
    private val GRID_SIZE = 30       // 网格大小（像素）
    val INIT_SPEED = 200     // 初始速度(毫秒)
    private val MOVE_STEP = 1.2f     // 移动步长
    private val FOOD_TOTAL_COUNT = 20 // 食物总数
    private val SNAKE_FOOD_OVERLAP = 1.5f // 蛇与食物重叠阈值
    private val FOOD_FOOD_OVERLAP = 1.2f // 食物间重叠阈值
    private val MAX_TRY_COUNT = 500   // 最大生成尝试次数
    private val SINGLE_FOOD_TRY = 100 // 单个食物尝试次数
    private val GAME_OVER_DELAY = 800L // 游戏结束延迟

    // 音乐相关
    private var mediaPlayer: MediaPlayer? = null
    private val BACKGROUND_MUSIC_RES_ID = R.raw.game_bg // 请替换为你的音乐资源ID
    private var deathMediaPlayer: MediaPlayer? = null // 死亡音效播放器
    private val DEATH_SOUND_RES_ID = R.raw.game_death // 死亡音效资源ID（替换为你的音效文件）
    // 食物颜色
    private val COLOR_NORMAL = Color.parseColor("#FFCC00")    // 普通食物(黄)
    private val COLOR_HIGH_SCORE = Color.parseColor("#FF3B30")// 高分食物(红)
    private val COLOR_SLOW_DOWN = Color.parseColor("#00C6FF") // 减速食物(蓝)

    // 游戏状态
    private var moveAngle: Float = 0f
    private val snake = mutableListOf<FloatArray>() // 蛇身坐标(x,y)
    private val foods = mutableListOf<FoodModel>()
    private var score = 0
    private var isGameOver = false
    private var isRunning = false
    private var listener: GameListener? = null
    private var isViewReady = false // 视图初始化标记

    // 食物数据类
    private data class FoodModel(
        val x: Float,
        val y: Float,
        val type: FoodType,
        val color: Int
    )

    // 食物类型
    private enum class FoodType {
        NORMAL, HIGH_SCORE, SLOW_DOWN
    }

    // 画笔
    private val snakePaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#4CD964") // 蛇身绿色
        style = Paint.Style.FILL
    }
    private val foodPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        style = Paint.Style.FILL
        strokeWidth = 2f
    }
    private val foodTipPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.WHITE
        textSize = 18f
        textAlign = Paint.Align.CENTER
    }
    private val textBgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#88000000") // 半透明黑
        style = Paint.Style.FILL
    }
    private val gameOverPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.WHITE
        textSize = 40f
        textAlign = Paint.Align.CENTER
        typeface = Typeface.DEFAULT_BOLD
    }
    private val gameOverBgPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
        color = Color.parseColor("#CC000000") // 深色半透明遮罩
        style = Paint.Style.FILL
    }

    // 游戏线程
    internal lateinit var gameThread: GameThread

    // 游戏结束回调接口
    fun interface GameListener {
        fun onGameOver(score: Int)
    }

    init {
        resetSnake()
        // 初始化音乐播放器
        initMediaPlayer()

        // 监听视图布局完成
        viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                if (width > 0 && height > 0) {
                    isViewReady = true
                    initAllFoods()
                    viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
            }
        })
        initGameThread()
    }


    // 播放背景音乐
    private fun initMediaPlayer() {
        if (mediaPlayer == null) {
            try {
                mediaPlayer = MediaPlayer.create(context, BACKGROUND_MUSIC_RES_ID)
                mediaPlayer?.isLooping = true // 循环播放
                mediaPlayer?.setVolume(0.5f, 0.5f)
            } catch (e: Exception) {
                mediaPlayer = null
            }
        }
    }
    // 初始化死亡音效播放器
    private fun initDeathSoundPlayer() {
        if (deathMediaPlayer == null) {
            try {
                deathMediaPlayer = MediaPlayer.create(context, DEATH_SOUND_RES_ID)
                deathMediaPlayer?.apply {
                    isLooping = false // 死亡音效仅播放一次
                    setVolume(0.8f, 0.8f) // 调整音效音量
                }
            } catch (e: Exception) {
                e.printStackTrace()
                deathMediaPlayer = null
            }
        }
    }
    // 开始播放背景音乐
    private fun startBackgroundMusic() {
        if (mediaPlayer == null) {
            initMediaPlayer()
        }
        mediaPlayer?.let {
            if (!it.isPlaying) {
                it.start()
            }
        }
    }

    // 停止背景音乐
    private fun stopBackgroundMusic() {
        mediaPlayer?.let {
            if (it.isPlaying) {
                it.pause()
                it.seekTo(0)
            }
        }
    }
    private fun playDeathSound() {
        if (deathMediaPlayer == null) {
            initDeathSoundPlayer() // 确保初始化完成
        }
        deathMediaPlayer?.let {
            if (!it.isPlaying) {
                it.seekTo(0) // 重置到开头（避免重复播放时只播后半段）
                it.start()
            }
        }
    }
    // 释放MediaPlayer资源（只保留这一个）
    private fun releaseMediaPlayer() {
        // 释放背景音乐
        mediaPlayer?.let {
            it.stop()
            it.release()
            mediaPlayer = null
        }
        // 释放死亡音效
        deathMediaPlayer?.let {
            it.stop()
            it.release()
            deathMediaPlayer = null
        }
    }
    // 初始化游戏线程
    private fun initGameThread() {
        if (::gameThread.isInitialized && gameThread.isAlive) {
            gameThread.interrupt()
        }
        gameThread = GameThread(INIT_SPEED)
        gameThread.start()
    }

    // 重置蛇
    private fun resetSnake() {
        snake.clear()
        val headX = 3f
        val headY = 3f
        snake.add(floatArrayOf(headX, headY))         // 蛇头
        snake.add(floatArrayOf(headX - 1, headY))     // 身体1
        snake.add(floatArrayOf(headX - 2, headY))     // 身体2
        snake.add(floatArrayOf(headX - 3, headY))     // 身体3
        snake.add(floatArrayOf(headX - 4, headY))     // 身体4
        moveAngle = 0f // 初始方向向右
    }

    // 初始化所有食物
    private fun initAllFoods() {
        if (!isViewReady) return
        foods.clear()
        var successCount = 0
        var totalTry = 0

        while (successCount < FOOD_TOTAL_COUNT && totalTry < MAX_TRY_COUNT) {
            if (generateSingleFood()) {
                successCount++
            }
            totalTry++
        }
    }

    // 生成单个食物
    private fun generateSingleFood(): Boolean {
        if (!isViewReady || width <= 0 || height <= 0) return false

        val maxGridX = (width / GRID_SIZE).toFloat().coerceAtLeast(5f) - 1f
        val maxGridY = (height / GRID_SIZE).toFloat().coerceAtLeast(5f) - 1f

        var isInvalid: Boolean
        var tryCount = 0

        do {
            isInvalid = false
            tryCount++

            // 随机坐标
            val foodX = Random.nextFloat() * maxGridX
            val foodY = Random.nextFloat() * maxGridY

            // 随机食物类型(普通60%，高分20%，减速20%)
            val foodType = when (Random.nextInt(10)) {
                0, 1 -> FoodType.HIGH_SCORE
                2, 3 -> FoodType.SLOW_DOWN
                else -> FoodType.NORMAL
            }

            // 食物颜色
            val foodColor = when (foodType) {
                FoodType.NORMAL -> COLOR_NORMAL
                FoodType.HIGH_SCORE -> COLOR_HIGH_SCORE
                FoodType.SLOW_DOWN -> COLOR_SLOW_DOWN
            }

            // 检查与蛇重叠
            for (part in snake) {
                if (kotlin.math.abs(part[0] - foodX) < SNAKE_FOOD_OVERLAP &&
                    kotlin.math.abs(part[1] - foodY) < SNAKE_FOOD_OVERLAP
                ) {
                    isInvalid = true
                    break
                }
            }

            // 检查与其他食物重叠
            if (!isInvalid) {
                for (existFood in foods) {
                    if (kotlin.math.abs(existFood.x - foodX) < FOOD_FOOD_OVERLAP &&
                        kotlin.math.abs(existFood.y - foodY) < FOOD_FOOD_OVERLAP
                    ) {
                        isInvalid = true
                        break
                    }
                }
            }

            if (!isInvalid) {
                foods.add(FoodModel(foodX, foodY, foodType, foodColor))
                return true
            }
        } while (isInvalid && tryCount < SINGLE_FOOD_TRY)

        return false
    }

    // 开始游戏
    fun startGame() {
        isGameOver = false
        isRunning = true
        score = 0
        moveAngle = 0f
        resetSnake()

        // 开始播放背景音乐
        startBackgroundMusic()

        if (isViewReady) {
            initAllFoods()
        } else {
            viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
                override fun onGlobalLayout() {
                    initAllFoods()
                    viewTreeObserver.removeOnGlobalLayoutListener(this)
                }
            })
        }
        initGameThread()
        invalidate()
    }

    // 加速
    fun boostSpeed(percent: Float = 0.3f) {
        if (::gameThread.isInitialized && gameThread.isAlive && isRunning && !isGameOver) {
            val newDelay = (gameThread.getCurrentDelay() * (1 - percent)).toInt()
            gameThread.updateDelay(newDelay.coerceAtLeast(50)) // 最低50ms
        }
    }

    // 设置移动角度
    fun setMoveAngle(angle: Float) {
        if (!isGameOver) {
            moveAngle = angle
        }
    }

    // 暂停游戏
    fun pauseGame() {
        isRunning = false
        stopBackgroundMusic()
    }

    // 绘制
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawColor(Color.parseColor("#1A1A1A")) // 深灰背景

        // 绘制蛇
        for (part in snake) {
            canvas.drawRect(
                part[0] * GRID_SIZE,
                part[1] * GRID_SIZE,
                (part[0] + 1) * GRID_SIZE,
                (part[1] + 1) * GRID_SIZE,
                snakePaint
            )
        }

        // 绘制食物
        for (food in foods) {
            foodPaint.color = food.color
            val centerX = (food.x + 0.5f) * GRID_SIZE
            val centerY = (food.y + 0.5f) * GRID_SIZE
            val size = GRID_SIZE / 2.5f

            // 绘制食物形状
            when (food.type) {
                FoodType.NORMAL -> canvas.drawCircle(centerX, centerY, size, foodPaint)
                FoodType.HIGH_SCORE -> canvas.drawRect(
                    centerX - size, centerY - size,
                    centerX + size, centerY + size,
                    foodPaint
                )
                FoodType.SLOW_DOWN -> {
                    val path = Path()
                    path.moveTo(centerX, centerY - size)
                    path.lineTo(centerX - size, centerY + size / 2)
                    path.lineTo(centerX + size, centerY + size / 2)
                    path.close()
                    canvas.drawPath(path, foodPaint)
                }
            }

            // 绘制描边
            foodPaint.color = Color.BLACK
            foodPaint.style = Paint.Style.STROKE
            when (food.type) {
                FoodType.NORMAL -> canvas.drawCircle(centerX, centerY, size, foodPaint)
                FoodType.HIGH_SCORE -> canvas.drawRect(
                    centerX - size, centerY - size,
                    centerX + size, centerY + size,
                    foodPaint
                )
                FoodType.SLOW_DOWN -> {
                    val path = Path()
                    path.moveTo(centerX, centerY - size)
                    path.lineTo(centerX - size, centerY + size / 2)
                    path.lineTo(centerX + size, centerY + size / 2)
                    path.close()
                    canvas.drawPath(path, foodPaint)
                }
            }
            foodPaint.style = Paint.Style.FILL
            foodPaint.color = food.color

            // 绘制食物提示文字
            val tipText = when (food.type) {
                FoodType.NORMAL -> "10"
                FoodType.HIGH_SCORE -> "+30"
                FoodType.SLOW_DOWN -> "减速"
            }
            val textWidth = foodTipPaint.measureText(tipText)
            canvas.drawRoundRect(
                centerX - textWidth / 2 - 4,
                centerY - size - 20,
                centerX + textWidth / 2 + 4,
                centerY - size,
                8f, 8f,
                textBgPaint
            )
            canvas.drawText(tipText, centerX, centerY - size - 6, foodTipPaint)
        }

        // 游戏结束画面
        if (isGameOver) {
            canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), gameOverBgPaint)
            canvas.drawText("游戏结束", width / 2f, height / 2f - 30, gameOverPaint)
            canvas.drawText("最终得分: $score", width / 2f, height / 2f + 30, gameOverPaint)
        }
    }

    // 游戏线程
    inner class GameThread(private var currentDelay: Int) : Thread() {
        fun getCurrentDelay() = currentDelay
        fun updateDelay(newDelay: Int) { currentDelay = newDelay }

        override fun run() {
            while (isRunning && !isGameOver) {
                moveSnake()
                postInvalidate()
                try {
                    Thread.sleep(currentDelay.toLong())
                } catch (e: InterruptedException) {
                    break
                }
            }
        }
    }

    // 蛇移动逻辑
    private fun moveSnake() {
        if (!isViewReady || width == 0 || height == 0 || isGameOver) return

        val head = snake[0]
        val dx = cos(moveAngle.toDouble()).toFloat() * MOVE_STEP
        val dy = sin(moveAngle.toDouble()).toFloat() * MOVE_STEP

        val newHeadX = head[0] + dx
        val newHeadY = head[1] + dy

        // 边界碰撞检测
        val maxGridX = (width / GRID_SIZE).toFloat() - 1
        val maxGridY = (height / GRID_SIZE).toFloat() - 1
        if (newHeadX < 0 || newHeadX > maxGridX || newHeadY < 0 || newHeadY > maxGridY) {
            gameOver()
            return
        }

        // 自身碰撞检测
        for (i in 1 until snake.size) {
            val part = snake[i]
            if (kotlin.math.abs(newHeadX - part[0]) < 0.7 && kotlin.math.abs(newHeadY - part[1]) < 0.7) {
                gameOver()
                return
            }
        }

        // 添加新蛇头
        snake.add(0, floatArrayOf(newHeadX, newHeadY))

        // 检测吃食物
        var eatenFoodIndex = -1
        for (index in foods.indices) {
            val food = foods[index]
            if (kotlin.math.abs(newHeadX - food.x) < 0.9 && kotlin.math.abs(newHeadY - food.y) < 0.9) {
                eatenFoodIndex = index
                // 处理食物效果
                when (food.type) {
                    FoodType.NORMAL -> score += 10
                    FoodType.HIGH_SCORE -> score += 30
                    FoodType.SLOW_DOWN -> {
                        score += 10
                        val newDelay = (gameThread.getCurrentDelay() * 1.1).toInt()
                        gameThread.updateDelay(newDelay.coerceAtMost((INIT_SPEED * 1.5).toInt()))
                    }
                }
                break
            }
        }

        if (eatenFoodIndex != -1) {
            foods.removeAt(eatenFoodIndex)
            generateSingleFood()
        } else {
            snake.removeAt(snake.size - 1)
        }
    }

    // 游戏结束
    fun gameOver() {
        if (isGameOver) return

        isGameOver = true
        isRunning = false

        // 1. 停止背景音乐
        stopBackgroundMusic()
        // 2. 播放死亡音效
        playDeathSound()

        if (::gameThread.isInitialized && gameThread.isAlive) {
            gameThread.interrupt()
        }

        postInvalidate() // 刷新结束画面

        postDelayed({
            listener?.onGameOver(score)
        }, GAME_OVER_DELAY)
    }

    // 设置监听器
    fun setGameListener(listener: GameListener) {
        this.listener = listener
    }

    // 获取当前分数
    fun getCurrentScore() = score


    // 生命周期处理
    override fun onDetachedFromWindow() {
        super.onDetachedFromWindow()
        isRunning = false
        if (::gameThread.isInitialized && gameThread.isAlive) {
            gameThread.interrupt()
        }
        // 释放音乐资源
        releaseMediaPlayer()

    }
}